<?php

namespace app\service;

/**
 * 令牌桶算法
 * Class TokenBucket
 */
class TokenBucket {

    private $last_req_time; //上次请求时间
    public $capacity; //桶的容量
    public $rate; //令牌放入的速度(个/秒)
    public $tokens; //当前可用令牌的数量

    public function __construct() {
        $this->last_req_time = time();
        $this->capacity = 100;
        $this->rate = 20;
        $this->tokens = 100; //开始给100个令牌
    }

    public function grant() {
        $now = time();
        $tokens = min($this->capacity, $this->tokens + ($now - $this->last_req_time) * $this->rate);// 计算桶里可用的令牌数
        $this->tokens = $tokens;
        $this->last_req_time = $now;
        if ($this->tokens < 1) {
            // 若剩余不到1个令牌，则拒绝
            return false;
        }
        // 还有令牌，领取1个令牌
        $this->tokens -= 1;
        return true;
    }
}